#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>

void Write(int fd)
{
    int cnt = 0;
    while (1)
    {
        char buff[1024];
        snprintf(buff, sizeof(buff), "I am chile, pid : %d, ppid : %d", getpid(), getppid());
        printf("cnt = %d\n", cnt++);
        write(fd, buff, strlen(buff));
        sleep(1);
    }
}
void Read(int fd)
{
    while (1)
    {
        char buff[1024];
        int n = read(fd, buff, sizeof(buff) - 1);
        if (n < 0) // 读取失败
        {
            perror("read");
            exit(1);
        }
        else if (n == 0)
        {
            printf("read return value : %d\n", n);
            continue;
        }
        buff[n] = 0;
        printf("read : %s\n",buff);
        sleep(2);
        break;
    }
}

// void Write(int fd)
// {
//     int cnt = 0;
//     while (1)
//     {
//         char buff[1024];
//         snprintf(buff, sizeof(buff), "I am chile, pid : %d, ppid : %d", getpid(), getppid());
//         printf("cnt = %d\n", cnt++);
//         write(fd, buff, strlen(buff));
//         break;
//     }
// }
// void Read(int fd)
// {
//     // printf("read begin:\n");
//     while (1)
//     {
//         sleep(1);
//         char buff[1024];
//         int n = read(fd, buff, sizeof(buff) - 1);
//         if (n < 0) // 读取失败
//         {
//             perror("read");
//             exit(1);
//         }
//         else if (n == 0)
//         {
//             printf("read return value : %d\n", n);
//         }
//         buff[n] = 0;
//         printf("read : %s\n",buff);
//         // printf("read end\n");
//         // printf("----------------------------------------------------------\n");//分割每一次读取的数据
//     }
// }

int main()
{
    int fd[2];
    int n = pipe(fd); // 创建管道文件
    if (n < 0)
    {
        perror("pipe");
        exit(1);
    }
    int id = fork();
    if (id < 0)
    {
        perror("fork");
        exit(2);
    }
    else if (id == 0)
    {
        // child -> w
        close(fd[0]); // 关闭不用的文件描述符
        Write(fd[1]); // 向fd[1]文件中写入
        close(fd[1]); // 写入完成后关闭fd[1]
        exit(1);      // 子进程退出
    }
    // parent -> r
    close(fd[1]); // 关闭不用的文件描述符
    Read(fd[0]);  // 在文件fd[0]中读数据
    close(fd[0]); // 读完成后关闭fd[0]
    sleep(1);
    int status;
    waitpid(id, &status, 0);
    printf("child exit : %d\n",status & 0x7F);
    sleep(3);
    return 0;
}

// int main()
// {
//     int fd[2];
//     int n = pipe(fd);
//     if(n<0){
//         perror("pipe");
//         exit(1);
//     }
//     printf("fd[0] : %d\n",fd[0]);
//     printf("fd[1] : %d\n",fd[1]);
//     return 0;
// }

// void Write(int fd)
// {
//     int cnt = 0;
//     while (1)
//     {
//         //sleep(1);
//         char buff[1024];
//         // snprintf(buff, sizeof(buff), "parent write, pid : %d", getpid());
//         snprintf(buff, sizeof(buff), "child write, pid : %d, ppid : %d", getpid(), getppid());
//         write(fd, buff, strlen(buff));
//         printf("cnt = %d\n",cnt++);
//         //break;
//     }
// }

// void Read(int fd)
// {
//     while (1)
//     {
//         //sleep(1);
//         char buff[1024];
//         int n = read(fd, buff, sizeof(buff));
//         if(n<0)
//         {
//             perror("read");
//             exit(1);
//         }
//         else if(n == 0)
//         {
//             break;
//         }
//         buff[n] = 0;
//         printf("parent read : %s\n", buff);
//         sleep(1);
//         break;
//     }
// }

// int main()
// {
//     // pipe创建匿名管道
//     int fd[2] = {0};
//     // 0 -> r    1 -> w
//     int n = pipe(fd);
//     if (n > 0)
//     {
//         perror("pipe");
//         exit(1);
//     }
//     int id = fork();
//     if (id < 0)
//     {
//         perror("fork");
//         exit(2);
//     }
//     else if (id == 0)
//     {
//         // child 读
//         // close(fd[1]); // 关闭多余的文件描述符
//         // read
//         // Read(fd[0]);

//         // child 写
//         close(fd[0]);
//         Write(fd[1]);
//         exit(1);
//     }
//     // parent read
//     close(fd[1]);
//     Read(fd[0]);
//     close(fd[0]);
//     sleep(3);
//     wait(NULL);

//     // parent 写
//     // close(fd[0]);
//     // write
//     // Write(fd[1]);
//     // wait(NULL);

//     sleep(10);
//     return 0;
// }